
#include "sc_gui.h"

//底层接口，与lvgl接口一样
void LCD_DMA_color(int xs, int ys, int xe, int ye, u16 *color)
{
#if 0
    SPI_DMA_color( xs,  ys,  xe,  ye,color);
#else
    //-----------------无DMA------------------------
    // LCD_SetWindows(xs, ys,xe, ye);
    for(int x = xs; x <=xe; x++)
    {
        for(int y = ys; y <=ye; y++)
        {
            gui->bsp_pset (x,y,*color);
            // LCD_Write_Dat16(*color);	//写入数据
            color++;
        }
    }
#endif
}
u16 DMA_buf_color[CPU_DMABUF_NUM][320] = {0};  //DMA内存屏幕大小
u16 *dma_prt=(u16*)DMA_buf_color;              //切换双buf
u16  dma_buf_index = 0;
//DMA连续画点
void Dma_pset(int x,int y,u16 a)
{
    if((gui->state&SC_STATE_IMAGE)==0)      //不是图片
    {
        if(gui->ram_pset)
        {
            gui->ram_pset( x, y, a);        //写内存
            if(gui->state&SC_STATE_STR_Refresh)
            {
                a=gui->ram->colour[a];     //字体同步到屏幕
            }
            else
            {
                return;
            }
        }
        else
        {
            a= gui->colour[a];            //取色器到屏幕
        }
    }
    dma_prt[dma_buf_index++]=a;
}
//空函数
int Dma_read(int x,int y,u16 *c)
{
    return 0;
}
//双buf按行刷新屏幕
void Dma_Refresh(int xs, int ys,int xe, int ye)
{
    if(dma_buf_index==0)  return;
//    if(gui->gbkg)
//    {
//        bkg=gui->gbkg->w*y+xs;
//        for(x=xs; x<xe; x++)
//        {
//            bc=*bkg;
//            if(gui->bkc!=0)
//            {
//                bc=SC_AlphaBlender(gui->bkc,*bkg,gui->alpha);  //带背景文字
//            }
//            *buf= SC_AlphaBlender(gui->fc,bc,buf[0]);
//            buf++;
//            bkg++;
//        }
//    }
    LCD_DMA_color(xs, ys,xe, ye,dma_prt);
    //-------------- 双BUF切换------------------------------
#if  (CPU_DMABUF_NUM==2)
    if(dma_prt==(u16*)&DMA_buf_color)
    {
        dma_prt= &DMA_buf_color[1][0];
    }
    else
    {
        dma_prt= &DMA_buf_color[0][0];
    }
#endif
    dma_buf_index = 0;
}

//显示图片，DMA加速
void Dma_Show_Image(int xs,int ys,SC_img_t *bmp)
{
    int x,y;
    u16 *bkg=(void*)&bmp->map;
    gui->state|=SC_STATE_IMAGE;       //图片直刷
    for(y=0; y<bmp->h; y++)
    {
        for(x=0; x<bmp->w; x++)
        {
            Dma_pset(x,y,bkg[x]);             //先复制到内存坐标检查用
        }
        Dma_Refresh(xs, y+ys,xs+bmp->w-1,y+ys);
        bkg+=bmp->w;
    }
    gui->state&=~SC_STATE_IMAGE;
    gui->gbkg=bmp;                         //用作背景
}

///==================2bbp内存池ac[0-3]表示4种色值============================
#if LCD_SCREEN_RAM_BUF
static u8 bit_ram_buf[LCD_SCREEN_RAM_SIZE];
//内存画点
void SC_RAM_pset(int xs,int ys,u16 a)
{
    u8 xb;
    u8 *map;
    if(xs<gui->ram->xs||xs>gui->ram->xe) return;
    if(ys<gui->ram->ys||ys>gui->ram->ye) return;
    xs-=gui->ram->xs;
    ys-=gui->ram->ys;
    map=gui->ram->buf+(gui->ram->buf_w*ys)+xs/4;
    xb=(3-xs%4)<<1;
    map[0]&=~(0x03<<xb);
    map[0]|= (a<<xb);
}
//内存读点
u8 SC_RAM_read(int xs,int ys,u16 *c)
{
    u8 xb;
    u8 *map;
    u8 ac;
    if(gui->ram==NULL)                   return 0;
    if(xs<gui->ram->xs||xs>gui->ram->xe) return 0;
    if(ys<gui->ram->ys||ys>gui->ram->ye) return 0;
    xs-=gui->ram->xs;
    ys-=gui->ram->ys;
    map=gui->ram->buf+(gui->ram->buf_w*ys)+xs/4;
    xb=(3-xs%4)<<1;
    ac=(map[0]>>xb)&0x03;
    *c= gui->ram->colour[ac];
    return ac;
}
//内存刷新
void SC_RAM_refresh(int xs,int ys,int xe,int ye)
{
    int x,y;
    u16 rc;
    if(gui->ram==NULL)  return;
    gui->state|=SC_STATE_IMAGE;
    for(x=xs; x<=xe; x++)
    {
        for(y=ys; y<=ye; y++)
        {
            SC_RAM_read(x,y,&rc);           //读点
            Dma_pset(x,y,rc);
        }
        Dma_Refresh(x, ys,x, ye);       //纵向输出
    }
    gui->state&=~SC_STATE_IMAGE;
}

/******************创建内存位图***************************
多个控件请使用malloc或自己多开几个bit_ram_buf[]
C1~C3:调色板
返回 ：1成功，0内存不足。*/
int SC_RAM_create(SC_RAM *ram,int xs,int ys,int xe,int ye,u16 c0,u16 c1,u16 c2,u16 c3)
{
    u16 size;
    ram->colour[0]=c0;
    ram->colour[1]=c1;
    ram->colour[2]=c2;
    ram->colour[3]=c3;
    ram->xs=xs;
    ram->xe=xe;
    ram->ys=ys;
    ram->ye=ye;
    ram->buf=NULL;
    ram->buf_w=((xe-xs+1)*2+7)/8;   //(width*2bbp+7)/8;
    size=(ye-ys+1)*ram->buf_w;
    if(size<=LCD_SCREEN_RAM_SIZE)
    {
        ram->buf= bit_ram_buf;
        // ram->buf= malloc(size);
        // memset(ram->buf,0,size);
        return size;
    }
    return 0;
}
//如果使用malloc
void SC_RAM_free(SC_RAM *ram)
{
    gui->ram= NULL;
    gui->ram_pset= NULL;
    free(ram->buf);
}
//内存图层开关
void SC_RAM_layou(SC_RAM *ram,u8 en)
{
    if(ram->buf&&en)
    {
        gui->ram= ram;
        gui->ram_pset= SC_RAM_pset;
    }
    else
    {
        gui->ram= NULL;
        gui->ram_pset= NULL;
    }
}
//================测试例程，位图格式不支持LVGL字体字写入===========================================
SC_RAM  box;
void SC_Demo_box(void)
{   u16 size;
    size=SC_RAM_create(&box,40,60,140,140,C_BLACK,C_BLUE,C_YELLOW,C_RED);
    if(size==0)
    {
        SC_Show_str1(box.xs,box.ys,A_C1,A_C0,"ram ovre", 0,gui->font);
        return;
    }
    //----------启动图层画色块--------------------
    SC_RAM_layou(&box,1);
    SC_RoundFrame1(box.xs,box.ys,box.xe,box.ye, 3,    A_C1);
    SC_RoundFrame1(box.xs,box.ys,box.xe,box.ys+30, 3, A_C2);
    //----------文本------------------
    SC_text_align((SC_AERA*)&box,SC_STATE_STR_MID);

    SC_Show_float(-30,6,A_C1,A_C2,size, 0,gui->font);
     SC_Show_str1(20,6,A_C1,A_C2,"byte ram", 0,gui->font);
    SC_Show_float(0,60,A_C3,A_C1,0, 0,gui->font);  //除100
    SC_text_align(NULL,0);
    //----------刷新退出图层-------------------
    SC_RAM_refresh(box.xs,box.ys,box.xe,box.ye);
    SC_RAM_layou(&box,0);


}
//----------------变更参数-------------------------
void SC_Demo_box_chart(u16 num)
{
    SC_AERA chart={20,80,180,160};
    static u16 last_num;
    SC_RAM_layou(&box,1);     //启动图层
    if(last_num!=num)
    {
        SC_text_align((SC_AERA*)&box,SC_STATE_STR_MID|SC_STATE_STR_Refresh); //居中并局部刷新
        SC_Show_float(0,60,A_C3,A_C1,num%30, 0,gui->font); //除10
        SC_text_align(NULL,0);
        //----------刷新退出图层-------------------
        //SC_RAM_refresh(box.xs,box.ys,box.xe,box.ye);   //局部刷新
    }
    last_num=num;
    SC_Show_chart(&chart,4,5,num%30,A_C1,A_C2);
    SC_RAM_layou(&box,0);

}

#endif


